package com.xhwl.centiotdata.handler.firefighting.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.firefighting.FirefightingFactory;
import com.xhwl.centiotdata.handler.firefighting.FirefightingHandler;
import com.xhwl.centiotdata.mq.producer.GeneralProducer;
import com.xhwl.centiotdata.pojo.constant.HuaWeiIoTDAConstant;
import com.xhwl.centiotdata.pojo.dto.firefighting.*;
import com.xhwl.centiotdata.service.cent.ICentAlarmService;
import com.xhwl.centiotdata.service.impl.DeviceServiceImpl;
import com.xhwl.common.constant.cent.alarm.AlarmConstant;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.device.iot.DeviceService;
import com.xhwl.common.dto.cent.device.iot.DeviceServiceBody;
import com.xhwl.common.dto.cent.device.iot.IotDeviceJson;
import com.xhwl.common.pojo.cent.alarm.AlarmLog;
import com.xhwl.common.pojo.cent.alarm.AlarmManagement;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @Author： lianghz
 * @Description：
 * @Date 2022/01/10/ 19:16
 */
@Slf4j
@Service
public class FirefightingHuaWeiIoTDAHandler extends FirefightingHandler {

    private final String RESULT_TRUE = "True";
    private final String ALARM_SMOKE = "89871720";
    private final String ALARM_TEMPERATURE = "17377241";
    private final String ALARM_MANUAL = "49433461";
    private final String ALARM_FIRE_HYDRANT = "89108483";
    private final String ALARM_WATER_FLOW_INDICATOR = "80291331";

    @Autowired
    private DeviceServiceImpl deviceService;
    @Autowired
    private GeneralProducer generalProducer;
    @Autowired
    private ICentAlarmService centAlarmService;

    @Override
    public void afterPropertiesSet() throws Exception {
        FirefightingFactory.register(1, this);
    }

    @Override
    public void pushSmoke(Object data, Integer projectId) {
        if (data instanceof IotDeviceJson) {
            IotDeviceJson<DeviceServiceBody<FireSmockAlarm>> requestBody;
            try {
                requestBody = (IotDeviceJson<DeviceServiceBody<FireSmockAlarm>>) data;
            } catch (Exception e) {
                log.error("pushSmoke data transform error ! {}", JSON.toJSONString(data));
                e.printStackTrace();
                return;
            }
            requestBody.getNotify_data().getBody().getServices().stream()
                    .forEach(deviceService -> {
                        AlarmLog alarmLog = new AlarmLog();
                        alarmLog.setTag(deviceService.getService_id());
                        alarmLog.setContent(JSONObject.toJSONString(deviceService));
                        alarmLog.setPushTime(new Date());
                        centAlarmService.insert(alarmLog);
                        if (HuaWeiIoTDAConstant.SERVICE_FIRE_SMOKE_ALARM.equals(deviceService.getService_id())
                                && !RESULT_TRUE.equals(deviceService.getProperties().getSmokeAlarmStatus())) {
                            this.sendAlarm(projectId, ALARM_SMOKE, requestBody.getNotify_data().getHeader().getDevice_id(), deviceService.getEvent_time());
                        }
                    });
        } else {
            log.error("pushSmoke data format error ! {}", JSON.toJSONString(data));
            return;
        }
    }

    @Override
    public void pushTemperature(Object data, Integer projectId) {
        if (data instanceof IotDeviceJson) {
            IotDeviceJson<DeviceServiceBody<FireTemperatureAlarm>> requestBody;
            try {
                requestBody = (IotDeviceJson<DeviceServiceBody<FireTemperatureAlarm>>) data;
            } catch (Exception e) {
                log.error("pushTemperature data transform error ! {}", JSON.toJSONString(data));
                e.printStackTrace();
                return;
            }
            requestBody.getNotify_data().getBody().getServices().stream()
                    .forEach(deviceService -> {
                        AlarmLog alarmLog = new AlarmLog();
                        alarmLog.setTag(deviceService.getService_id());
                        alarmLog.setContent(JSONObject.toJSONString(deviceService));
                        alarmLog.setPushTime(new Date());
                        centAlarmService.insert(alarmLog);
                        if (HuaWeiIoTDAConstant.SERVICE_FIRE_TEMPERATURE_ALARM.equals(deviceService.getService_id())
                                && !RESULT_TRUE.equals(deviceService.getProperties().getTemperatureAlarmAtatus())) {
                            this.sendAlarm(projectId, ALARM_TEMPERATURE, requestBody.getNotify_data().getHeader().getDevice_id(), deviceService.getEvent_time());
                        }
                    });
        } else {
            log.error("pushTemperature data format error ! {}", JSON.toJSONString(data));
            return;
        }
    }

    @Override
    public void pushManualAlarm(Object data, Integer projectId) {
        if (data instanceof IotDeviceJson) {
            IotDeviceJson<DeviceServiceBody<FireManualAlarm>> requestBody;
            try {
                requestBody = (IotDeviceJson<DeviceServiceBody<FireManualAlarm>>) data;
            } catch (Exception e) {
                log.error("pushManualAlarm data transform error ! {}", JSON.toJSONString(data));
                e.printStackTrace();
                return;
            }
            requestBody.getNotify_data().getBody().getServices().stream()
                    .forEach(deviceService -> {
                        AlarmLog alarmLog = new AlarmLog();
                        alarmLog.setTag(deviceService.getService_id());
                        alarmLog.setContent(JSONObject.toJSONString(deviceService));
                        alarmLog.setPushTime(new Date());
                        centAlarmService.insert(alarmLog);
                        if (HuaWeiIoTDAConstant.SERVICE_FIRE_MANUAL_ALARM.equals(deviceService.getService_id())
                                && !RESULT_TRUE.equals(deviceService.getProperties().getManualAlarmStatus())) {
                            this.sendAlarm(projectId, ALARM_MANUAL, requestBody.getNotify_data().getHeader().getDevice_id(), deviceService.getEvent_time());
                        }
                    });
        } else {
            log.error("pushManualAlarm data format error ! {}", JSON.toJSONString(data));
            return;
        }
    }

    @Override
    public void pushFireHydrant(Object data, Integer projectId) {
        if (data instanceof IotDeviceJson) {
            IotDeviceJson<DeviceServiceBody<FireFireHydrantAlarm>> requestBody;
            try {
                requestBody = (IotDeviceJson<DeviceServiceBody<FireFireHydrantAlarm>>) data;
            } catch (Exception e) {
                log.error("pushFireHydrant data transform error ! {}", JSON.toJSONString(data));
                e.printStackTrace();
                return;
            }
            requestBody.getNotify_data().getBody().getServices().stream()
                    .forEach(deviceService -> {
                        AlarmLog alarmLog = new AlarmLog();
                        alarmLog.setTag(deviceService.getService_id());
                        alarmLog.setContent(JSONObject.toJSONString(deviceService));
                        alarmLog.setPushTime(new Date());
                        centAlarmService.insert(alarmLog);
                        if (HuaWeiIoTDAConstant.SERVICE_FIRE_FIRE_HYDRANT_ALARM.equals(deviceService.getService_id())
                                && !RESULT_TRUE.equals(deviceService.getProperties().getFireHydrantAlarmStatus())) {
                            this.sendAlarm(projectId, ALARM_FIRE_HYDRANT, requestBody.getNotify_data().getHeader().getDevice_id(), deviceService.getEvent_time());
                        }
                    });
        } else {
            log.error("pushFireHydrant data format error ! {}", JSON.toJSONString(data));
            return;
        }
    }

    @Override
    public void pushWaterFlowIndicator(Object data, Integer projectId) {
        if (data instanceof IotDeviceJson) {
            IotDeviceJson<DeviceServiceBody<FireWaterFlowIndicatorAlarm>> requestBody;
            try {
                requestBody = (IotDeviceJson<DeviceServiceBody<FireWaterFlowIndicatorAlarm>>) data;
            } catch (Exception e) {
                log.error("pushWaterFlowIndicator data transform error ! {}", JSON.toJSONString(data));
                e.printStackTrace();
                return;
            }
            requestBody.getNotify_data().getBody().getServices().stream()
                    .forEach(deviceService -> {
                        AlarmLog alarmLog = new AlarmLog();
                        alarmLog.setTag(deviceService.getService_id());
                        alarmLog.setContent(JSONObject.toJSONString(deviceService));
                        alarmLog.setPushTime(new Date());
                        centAlarmService.insert(alarmLog);
                        if (HuaWeiIoTDAConstant.SERVICE_FIRE_WATER_FLOW_INDICATOR_ALARM.equals(deviceService.getService_id())
                                && !RESULT_TRUE.equals(deviceService.getProperties().getWaterFlowIndicatorAlarmStatus())) {
                            this.sendAlarm(projectId, ALARM_WATER_FLOW_INDICATOR, requestBody.getNotify_data().getHeader().getDevice_id(), deviceService.getEvent_time());
                        }
                    });
        } else {
            log.error("pushWaterFlowIndicator data format error ! {}", JSON.toJSONString(data));
            return;
        }
    }

    private void sendAlarm(Integer projectId, String alarmCode, String iotDeviceId, Date eventTime) {
        List<DeviceDTO> deviceDTOS = deviceService.findDevice(projectId, iotDeviceId);

        AlarmManagement alarmManagement = new AlarmManagement();
        alarmManagement.setProjectId(projectId);
        alarmManagement.setAlarmTime(eventTime);
        alarmManagement.setAlarmInventoryCode(alarmCode);
        alarmManagement.setDeviceId(deviceDTOS.get(0).getId());
        log.info("Firefighting Alarm : {}", JSON.toJSONString(alarmManagement));
        generalProducer.send(AlarmConstant.JINMAO_TOPIC, alarmManagement);
    }

}

